package com.codefish.codefishseckill.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.codefish.codefishseckill.entity.SecKillGoods;
import com.codefish.codefishseckill.entity.User;
import com.codefish.codefishseckill.mapper.SecKillGoodsMapper;
import com.codefish.codefishseckill.service.SecKillGoodsService;
import com.codefish.codefishseckill.utils.UuidUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * <p>
 * 秒杀商品表 服务实现类
 * </p>
 *
 * @author codefish
 * @since 2022-07-07
 */
@Service
public class SecKillGoodsServiceImpl extends ServiceImpl<SecKillGoodsMapper, SecKillGoods> implements SecKillGoodsService {
    @Autowired
    SecKillGoodsMapper mapper;

    @Autowired
    RedisTemplate<String, Object> redisTemplate;

    @Override
    @Transactional
    public boolean updateStock(Long goodsId, Integer newStock) {
        try {
            mapper.updateStockById(goodsId, newStock);
            return true;
        } catch (Exception e) {
            return false;
        }
    }


    @Override
    public boolean updateStockV1(Long goodsId, Integer downCount) {
        try {
            return mapper.updateStockByIdV1(goodsId, downCount);
        } catch (Exception e) {
            return false;
        }
    }

    @Override
    public boolean updateStockV2(Long goodsId, Integer downCount) {
        try {
            return mapper.updateStockByIdV2(goodsId, downCount);
        } catch (Exception e) {
            return false;
        }
    }

    @Override
    public SecKillGoods getByGoodsId(Long goodsId) {
        SecKillGoods secKillGoods = (SecKillGoods) redisTemplate.opsForValue().get(SECKILL_GOODS_PREFIX + goodsId);
        if (secKillGoods != null) {
            return secKillGoods;
        }

        QueryWrapper<SecKillGoods> wrapper = new QueryWrapper<>();
        wrapper.eq("goods_id", goodsId);
        secKillGoods = getOne(wrapper);
        redisTemplate.opsForValue().set(SECKILL_GOODS_PREFIX + goodsId, secKillGoods);
        return secKillGoods;
    }


    @Override
    public boolean recordKillSuccessUser(Long goodsId, Long userId) {

        Boolean haveKilled = redisTemplate.opsForSet().isMember(SecKillGoodsService.SECKILL_SUCCESS_PREFIX + goodsId, userId);
        //对这个商品已经秒杀过
        if (haveKilled != null && haveKilled) {
            return true;
        }
        //记录秒杀的用户
        redisTemplate.opsForSet().add(SecKillGoodsService.SECKILL_SUCCESS_PREFIX + goodsId, userId);
        return false;
    }

    @Override
    public boolean updateByGoodsId(SecKillGoods goods) {
        if (goods == null) {
            return false;
        }
        UpdateWrapper<SecKillGoods> wrapper = new UpdateWrapper<>();
        wrapper.eq("goods_id", goods.getGoodsId());

        return this.update(goods, wrapper);
    }

    @Override
    public String getPath(User user, Long goodsId) {
        String path = UuidUtils.randomUUID();
        String redisKey = goodsId + "-" + user.getUsername();
        redisTemplate.opsForValue().set(SECKILL_API_REAL_PATH_PREFIX + redisKey, path);
        return path;
    }

    @Override
    public boolean checkPath(String path, User user, Long goodsId) {
        String redisKey = goodsId + "-" + user.getUsername();
        String redisPath = (String) redisTemplate.opsForValue().get(SECKILL_API_REAL_PATH_PREFIX + redisKey);
        return path.equals(redisPath);
    }
}
